﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Tressel_asm
{
    class OpCode : InstructionComponentBase
    {
        /*#
       Variable Name: labelReq
       Module Where Defined: OpCode
       Data Type: string
       Local or Global: Global
       Purpose: Contains information regarding whether or not the opcode requires a label or not
       #*/
        private string labelReq;

        /*#
       Variable Name: operandReq
       Module Where Defined: OpCode
       Data Type: string
       Local or Global: Global
       Purpose: Contains information regarding what time of operand the opcode must have.
       #*/
        private string operandReq;
        /*#
       Variable Name: takesUpMemory
       Module Where Defined: OpCode
       Data Type: string
       Local or Global: Global
       Purpose: Contains information regarding if the instruction takes up memory.
       #*/
        private string takesUpMemory;
        /*#
       Variable Name: binaryCode
       Module Where Defined: OpCode
       Data Type: string
       Local or Global: Global
       Purpose: Contains the binary code of the opcode
       #*/
        private string binaryCode;
        public OpCode(string opCodeString, Instruction instructionReference)
        {
            /*!
            Procedure Name: OpCode
            Description: Overloaded constructor for OpCode class.
                         Calls AddError from Instruction instructionReference if string OpCodeString violates syntax
                         (see error conditions) or it is in neither directive table nor instruction table(not case sensitive).
            Input Parameters: string opCodeString, Instruction instructionReference
            Output Parameters: none
            Error Conditions Tested: 
            Error Messages Generated: 
                5) Second column must be a directive or instruction        
            Original Author: Louis Pan and Ryan McDanial
            Procedure Creation Date: 10/8/2009
            Modification Log:
            Who: Greg Loesch
            When: 10/18/09
            Why: Added DED information to variables and coded portion that searches for and sets labelReq and operandReq
            Coding Standards Met: SR
            Testing Standards Met: RM
            !*/
            this.text = opCodeString.ToUpper(); // setting up initial property value
            if (text.Length > 0)
            {
                /*#
                Variable Name: resultsArray
                Module Where Defined: OpCode
                Data Type: DataRow[]
                Local or Global: Local
                Purpose: Holds Data Rows returned from the opcode search. This is used to determine labelReq and operandReq 
                #*/
                DataRow[] resultsArray = new DataRow[0];
                /*#
                Variable Name: isValidOpcode
                Module Where Defined: OpCode
                Data Type: bool
                Local or Global: Local
                Purpose: boolean value to keep track of valid opcode.
                #*/
                bool isValidOpcode = true;
                try
                {
                    resultsArray = instructionReference.TresselReference.InstructionsDirectivesTable.Select("OPCODE='" + this.text + "'");
                }
                catch
                {
                    isValidOpcode = false;
                }

                if (resultsArray.Length == 0 || !isValidOpcode)
                {
                    instructionReference.AddError(5);
                    this.errorFlag = true;
                }
                else
                { //It's legal so determine if label and operand are required
                    labelReq = resultsArray[0]["LABEL"].ToString().Trim();
                    binaryCode = resultsArray[0]["BINARY"].ToString().Trim();
                    operandReq = resultsArray[0]["OPERAND"].ToString().Trim();
                    takesUpMemory = resultsArray[0]["MEMORY"].ToString().Trim();
                }
            }
            else
            {
                instructionReference.AddError(5);
                errorFlag = true;
            }
        }
        public OpCode()
        {
            /*!
            Procedure Name: OpCode (version 2)
            Description: Overloaded constructor for OpCode class.
            Input Parameters: none
            Output Parameters: none
            Error Conditions Tested: 
            Error Messages Generated: 
            Original Author: Steve Rudy
            Procedure Creation Date: 10/18/2009
            Modification Log:
            Coding Standards Met: SR
            Testing Standards Met: RM
            !*/
        }
        public string LabelReq
        {
            /*!
            Procedure Name: LabelReq
            Description: Gets or sets label requirement for the valid opcode
            Input Parameters: none
            Output Parameters: String
            Error Conditions Tested: 
            Error Messages Generated:        
            Original Author: Greg Loesch
            Procedure Creation Date: 10/18/2009
            Modification Log:
            Who: Steve Rudy
            When: 10/20/2009
            Why: The method needs to be converted to a property to both get and set the label req's
            Coding Standards Met: SR
            Testing Standards Met: RM
        !*/
            get
            {
                return labelReq;
            }
            set
            {
                labelReq = value;
            }
        }

        /*!
            Procedure Name: OperandReq
            Description: Returns the operand requirement for the valid opcode
            Input Parameters: none
            Output Parameters: String
            Error Conditions Tested: 
            Error Messages Generated:        
            Original Author: Greg Loesch
            Procedure Creation Date: 10/18/2009
            Modification Log:
            Who: Steve Rudy
            When: 10/27/2009
            Why: the method needs to become a property
            Coding Standards Met: SR
            Testing Standards Met: RM
        !*/
        public string OperandReq
        {
            get
            {
                return operandReq;
            }
        }
        public string TakesUpMemory
        {
            /*!
            Procedure Name: GetTakesUpMemory
            Description: Returns the takesUpMemory private variable
            Input Parameters: none
            Output Parameters: String
            Error Conditions Tested: 
            Error Messages Generated:        
            Original Author: Steve Rudy
            Procedure Creation Date: 10/19/2009
            Modification Log:
            Who: 
            When: 
            Why:
            Coding Standards Met: SR
            Testing Standards Met: RM
        !*/
            get
            {
                return takesUpMemory;
            }
            set
            {
                takesUpMemory = value;
            }
        }
        public string BinaryCode
        {
            /*!
            Procedure Name: BinaryCode
            Description: Gets or sets binaryCode
            Input Parameters: none
            Output Parameters: string
            Error Conditions Tested: 
            Error Messages Generated:        
            Original Author: Steve Rudy
            Procedure Creation Date: 10/26/2009
            Modification Log:
            Coding Standards Met: SR
            Testing Standards Met: RM
        !*/
            get
            {
                return binaryCode;
            }
            set
            {
                binaryCode = value;
            }
        }
    }
}
